import binascii
import ctypes
import logging
from ctypes import *
import queue

import numpy as np
from dbc import DBCParser
from zlgcan import *
from zuds_structure import *
import platform
import threading
import time
import datetime
import os  # 添加os模块导入
from zlgdbc import *

current_dir = os.path.dirname(os.path.abspath(__file__))    # 获取当前文件所在目录
parent_dir = os.path.dirname(current_dir)   # 获取当前文件所在目录的上层目录
grand_parent_dir = os.path.dirname(parent_dir)  # 获取上层目录的再上一层目录
sys.path.append(grand_parent_dir)   # 将再上一层目录添加到 sys.path 中
import Set_up

# 配置logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 全局变量,用于控制接收线程的启动和停止
START_RECEIVE_FLAG = 0

# 定义全局变量 zcanlib
zcanlib = ZCAN()


# 定义结构体用于存放UDS的参数内容
class PARAM_DATA(Structure):
    _pack_ = 1
    _fields_ = [("data", c_ubyte * 4096)]

# 定义通道参数结构体
class CHANNEL_PARAM(Structure):
    _fields_ = [
        ("channel_handle", c_uint32),  # 通道句柄
        ("Extend_Flag", c_uint32),  # 0-standard_frame, 1-extern_frame
        ("CANFD_type", c_uint32),  # 0-can,1-canfd
        ("trans_version", c_uint32)  # 0-ISO15765-2004,1-ISO15765-2016
    ]

# 发送回调函数,用于将UDS帧转换为CAN或CANFD帧并发送
@WINFUNCTYPE(c_uint32, POINTER(CHANNEL_PARAM), POINTER(ZUDS_FRAME), c_uint32)
def transmit_callback(ctx, frame, count):
    """优化后的发送回调函数,支持CAN和CANFD帧发送"""
    try:
        # 预计算常用值
        ctx_contents = ctx.contents
        is_canfd = ctx_contents.CANFD_type
        is_extended = ctx_contents.Extend_Flag
        
        if is_canfd:
            # CANFD帧处理
            zcanfd_data = (ZCAN_TransmitFD_Data * count)()
            memset(zcanfd_data, 0, sizeof(zcanfd_data))
            for i in range(count):
                frame_data = zcanfd_data[i].frame
                frame_data.can_id = frame[i].id
                if is_extended:
                    frame_data.eff = 1
                frame_data.len = frame[i].data_len
                frame_data.__pad = 0x08  # 设置发送回显
                # 使用内存拷贝提高数据复制效率
                ctypes.memmove(
                    frame_data.data, 
                    frame[i].data, 
                    min(frame[i].data_len, len(frame_data.data))
                )
            result = zcanlib.TransmitFD(ctx_contents.channel_handle, zcanfd_data, count)
        else:
            # CAN帧处理
            zcan_data = (ZCAN_Transmit_Data * count)()
            memset(zcan_data, 0, sizeof(zcan_data))
            for i in range(count):
                frame_data = zcan_data[i].frame
                frame_data.can_id = frame[i].id
                if is_extended:
                    frame_data.eff = 1
                frame_data.can_dlc = frame[i].data_len
                # 使用内存拷贝提高数据复制效率
                ctypes.memmove(
                    frame_data.data, 
                    frame[i].data, 
                    min(frame[i].data_len, len(frame_data.data))
                )
            result = zcanlib.Transmit(ctx_contents.channel_handle, zcan_data, count)
            
        return 0 if result == count else 1
    except Exception as e:
        logging.error(f"Error in transmit_callback: {e}", exc_info=True)
        return 1

# 全局变量,用于控制是否保存日志到文件
SAVE_LOG_FLAG = False
# 日志文件名
LOG_FILE_NAME = "canfd_specific_log.txt"

# UDS库类,封装了UDS库的操作
class ZUDS:
    def __init__(self):
        try:
            if platform.system() == "Windows":
                try:
                    # 尝试加载 commDriver/zlg/zuds.dll
                    self._dll = windll.LoadLibrary("commDriver/zlg/zuds.dll")
                except FileNotFoundError:
                    # 若 commDriver/zlg/zuds.dll 不存在,尝试加载 ./zuds.dll
                    self._dll = windll.LoadLibrary("./zuds.dll")
            else:
                logging.warning("No support now!")
                self._dll = None
            if self._dll is None:
                raise FileNotFoundError("DLL couldn't be loaded!")
        except Exception as e:
            logging.error(f"Error loading DLL: {e}")

    def _call_dll_function(self, func_name, *args):
        func = getattr(self._dll, func_name, None)
        if func:
            try:
                return func(*args)
            except Exception as e:
                logging.error(f"Exception on {func_name}: {e}")
        return None

    def Uds_Init(self, type_):
        return self._call_dll_function("ZUDS_Init", type_)

    def Uds_SetTransmitHandler(self, zuds_handle, ctx):
        return self._call_dll_function("ZUDS_SetTransmitHandler", zuds_handle, ctx, transmit_callback)

    def Uds_Request(self, handle, request, response):
        return self._call_dll_function("ZUDS_Request", handle, byref(request), byref(response))

    def Uds_Onreceive(self, handle, uds_frame):
        return self._call_dll_function("ZUDS_OnReceive", handle, byref(uds_frame))

    def Uds_SetParam(self, handle, type_, param):
        return self._call_dll_function("ZUDS_SetParam", handle, type_, byref(param))

    def Uds_SetTesterPresent(self, handle, enable, param):
        return self._call_dll_function("ZUDS_SetTesterPresent", handle, enable, byref(param))

    def Uds_Release(self, handle):
        return self._call_dll_function("ZUDS_Release", handle)

    def Uds_Stop(self, handle):
        return self._call_dll_function("ZUDS_Stop", handle)


class UDSController:
    """
    UDSController类封装了UDS通信的主要操作,包括CAN设备的打开、UDS的初始化、请求的发送和响应的处理等。
    """
    def __init__(self,device_type=ZCAN_USBCANFD_200U, device_index=0,chn_index=0,abit=500000,bbit=2000000):
        """
        初始化UDSController类的实例。
        初始化ZCAN和ZUDS库的实例,并将设备句柄、通道句柄、UDS句柄等初始化为None。
        """
        self.zcanlib = ZCAN()
        self.zudslib = ZUDS()
        self.zdbclib = DBCProcessor()
        self.device_handle = None
        self.chn_handle_0 = None
        self.uds_handle = None
        self.chn_param = None
        self.read_thread_ = None
        self.device_type = device_type
        self.device_index = device_index
        self.chn_index = chn_index
        self.abit = abit
        self.bbit = bbit
        self.current_data = []  # 新增属性,用于存储当前要发送的数据
        self.signal_cantype_dict={}  # 用于存储每个信号ID对应的CAN类型
        self.signal_data_dict = {}  # 用于存储每个信号ID对应的当前数据
        self.signal_thread_dict = {}  # 用于存储每个信号ID对应的线程
        self.signal_stop_event_dict = {}  # 用于存储每个信号ID对应的停止事件
        self.signal_pause_event_dict = {}  # 用于存储每个信号ID的暂停事件
        self.frame_timestamps = {}  # 新增：存储报文ID和最后时间戳的字典

        self.signal_monitor_thread = None
        self.signal_monitor_running = threading.Event()
        self.signal_monitor_interval = 0.1  # 默认监控间隔100ms
        self.signal_change_callbacks = {}  # 信号变化回调函数字典

        self.signal_receive_callbacks = {}  # 新增信号接收回调字典
        self.received_signal_data = {}     # 新增接收数据存储

        # 新增日志队列和工作线程
        self.log_queue = queue.Queue()
        self.log_thread = threading.Thread(target=self.log_worker, daemon=True)
        self.log_thread.start()

        self.condition_timestamps = {} # 存储条件匹配的时间戳

    
    def _handle_received_signal(self, frame_id, data):
        """处理接收到的信号数据"""
        # 记录原始数据
        self.received_signal_data[frame_id] = data
        
        # 触发注册的回调
        if frame_id in self.signal_receive_callbacks:
            try:
                self.signal_receive_callbacks[frame_id](frame_id, data)
            except Exception as e:
                logging.error(f"Signal receive callback error: {str(e)}")

    def register_signal_receiver(self, frame_id, callback):
        """
        注册信号接收回调
        :param frame_id: 要监听的信号ID 
        :param callback: 回调函数格式: func(frame_id, data)
        """
        self.signal_receive_callbacks[frame_id] = callback

    def unregister_signal_receiver(self, frame_id):
        """注销信号接收监听"""
        if frame_id in self.signal_receive_callbacks:
            del self.signal_receive_callbacks[frame_id]


    def get_frame_interval(self, frame_id):
        """
        获取指定报文ID的接收间隔
        :param frame_id: 要检测的报文ID
        :return: 与上一帧的间隔时间（秒）,如果是首帧返回None
        """
        current_time = time.time()
        if frame_id in self.frame_timestamps:
            interval = current_time - self.frame_timestamps[frame_id]
            self.frame_timestamps[frame_id] = current_time
            return interval
        else:
            self.frame_timestamps[frame_id] = current_time
            return None


    # 设置UDS参数的函数
    def Set_param(self, uds_handle, chn_param):
        """
        设置UDS的传输层和应用层参数。
        :param uds_handle: UDS句柄
        :param chn_param: 通道参数
        """
        try:
            # 传输层参数
            param_15765 = ZUDS_ISO15765_PARAM()
            memset(byref(param_15765), 0, sizeof(param_15765))
            param_15765.version = chn_param.trans_version
            param_15765.max_data_len = 64 if chn_param.trans_version else 8
            param_15765.local_st_min = 0
            param_15765.block_size = 0 #8
            param_15765.fill_byte = 0
            param_15765.frame_type = chn_param.Extend_Flag
            param_15765.is_modify_ecu_st_min = 0
            param_15765.remote_st_min = 0
            param_15765.fc_timeout = 100
            param_15765.fill_mode = 1
            self.zudslib.Uds_SetParam(uds_handle, 1, param_15765)

            # 应用层参数
            param_seesion = ZUDS_SESSION_PARAM()
            memset(byref(param_seesion), 0, sizeof(param_seesion))
            param_seesion.timeout = 2000
            param_seesion.enhanced_timeout = 5000
            self.zudslib.Uds_SetParam(uds_handle, 0, param_seesion)
            logging.info("set_param completed")
        except Exception as e:
            logging.error(f"Error setting parameters: {e}")

    # 自定义日志记录函数,将日志写入文件
    def log_to_file(self,message):
        global SAVE_LOG_FLAG, LOG_FILE_NAME
        if SAVE_LOG_FLAG:
            try:
                # 获取日志文件所在的目录
                log_dir = os.path.dirname(LOG_FILE_NAME)
                # 如果目录不存在,则创建目录
                if log_dir and not os.path.exists(log_dir):
                    os.makedirs(log_dir)
                with open(LOG_FILE_NAME, 'a', encoding='utf-8') as f:
                    current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    # log_line = f'{current_time} - INFO - {message}\n'
                    log_line = f'{message}\n'
                    f.write(log_line)
            except Exception as e:
                print(f"Error writing to log file: {e}")

    # 开始保存日志
    def start_logging(self, file_name):
        global SAVE_LOG_FLAG, LOG_FILE_NAME
        LOG_FILE_NAME = file_name
        SAVE_LOG_FLAG = True
        self.log_to_file("Logging started.")

    # 停止保存日志
    def stop_logging(self):
        global SAVE_LOG_FLAG
        self.log_to_file("Logging stopped.")
        SAVE_LOG_FLAG = False

    def add_condition_monitor(self, target_id, target_data=None):
        """
        添加条件监控
        :param target_id: 要监控的CAN ID
        :param target_data: 要匹配的数据列表,None表示不检查数据
        """
        self.condition_timestamps[target_id] = {
            'data': target_data,
            'timestamp': None
        }
        strData = binascii.b2a_hex(bytearray(target_data),' ')
        # logging.info(f"已添加条件监控: ID 0x{target_id:X}, 数据: {strData}")

    def get_first_match_timestamp(self, target_id):
        """
        获取符合条件的第一帧时间戳
        :param target_id: 要查询的CAN ID
        :return: 时间戳(秒)或None
        """
        return self.condition_timestamps.get(target_id, {}).get('timestamp')

    # 接收线程函数,用于接收CAN或CANFD数据并传递给UDS库处理
    def Read_Thread_Func(self, chn_handle, uds_handle):
        """
        接收线程函数,用于接收CAN或CANFD数据并传递给UDS库处理。
        :param chn_handle: 通道句柄
        :param uds_handle: UDS句柄
        """
        try:
            uds_frame = ZUDS_FRAME()
            while START_RECEIVE_FLAG:
                rcv_num = self.zcanlib.GetReceiveNum(chn_handle, ZCAN_TYPE_CAN)
                rcv_canfd_num = self.zcanlib.GetReceiveNum(chn_handle, ZCAN_TYPE_CANFD)
                if rcv_num:
                    rcv_msg, rcv_num = self.zcanlib.Receive(chn_handle, rcv_num, 1)
                    for i in range(rcv_num):
                        memset(byref(uds_frame), 0, sizeof(uds_frame))
                        uds_frame.id = rcv_msg[i].frame.can_id & 0x1fffffff
                        uds_frame.extend = rcv_msg[i].frame.eff
                        uds_frame.data_len = rcv_msg[i].frame.can_dlc
                        for j in range(uds_frame.data_len):
                            uds_frame.data[j] = rcv_msg[i].frame.data[j]
                        self.zudslib.Uds_Onreceive(uds_handle, uds_frame)

                        if uds_frame.id in self.condition_timestamps and self.condition_timestamps[uds_frame.id]['timestamp'] is None:
                            target_data = self.condition_timestamps[uds_frame.id]['data']
                            logging.debug(f"检查条件匹配: ID 0x{uds_frame.id:X} 目标数据: {target_data} 实际数据: {uds_frame.data[:len(target_data)] if target_data else 'None'}")
                            if target_data is None or uds_frame.data[:len(target_data)] == target_data:
                                self.condition_timestamps[uds_frame.id]['timestamp'] = rcv_msg[i].timestamp / 1000000.0
                                logging.info(f"记录到ID 0x{uds_frame.id:X}条件匹配时间戳: {self.condition_timestamps[uds_frame.id]['timestamp']}")

                         # 新增间隔检测
                        interval = self.get_frame_interval(rcv_msg[i].frame.can_id)
                        # if interval is not None:
                        #     logging.info(f"Frame ID 0x{rcv_msg[i].frame.can_id:X} interval: {interval*1000:.2f}ms")
                        
                        # 增加队列状态监控
                        # if self.log_queue.qsize() > 1000:
                        #     logging.warning(f"日志队列积压 {self.log_queue.qsize()} 条,可能影响实时性")
                        # 增加重试机制
                        for retry in range(3):
                            try:
                                log_entry = (
                                    rcv_msg[i].timestamp/1000000,
                                    'CAN',
                                    self.chn_index+1,
                                    "TX" if (rcv_msg[i].frame._pad & 0x20) else "RX",
                                    rcv_msg[i].frame.can_id,
                                    rcv_msg[i].frame.can_dlc,
                                    [rcv_msg[i].frame.data[j] for j in range(rcv_msg[i].frame.can_dlc)]
                                )
                                self.log_queue.put(log_entry, timeout=0.1)
                                break
                            except queue.Full:
                                if retry == 2:
                                    logging.error("日志队列已满,丢弃CAN帧数据")
                                else:
                                    time.sleep(0.01)

                        frame_id = rcv_msg[i].frame.can_id
                        data = [rcv_msg[i].frame.data[j] for j in range(rcv_msg[i].frame.can_dlc)]
                        self._handle_received_signal(frame_id, data)

                if rcv_canfd_num:
                    rcv_canfd_msgs, rcv_canfd_num = self.zcanlib.ReceiveFD(chn_handle, rcv_canfd_num, 1)
                    for i in range(rcv_canfd_num):
                        memset(byref(uds_frame), 0, sizeof(uds_frame))
                        uds_frame.id = rcv_canfd_msgs[i].frame.can_id & 0x1fffffff
                        uds_frame.extend = rcv_canfd_msgs[i].frame.eff
                        uds_frame.data_len = rcv_canfd_msgs[i].frame.len
                        for j in range(uds_frame.data_len):
                            uds_frame.data[j] = rcv_canfd_msgs[i].frame.data[j]
                        self.zudslib.Uds_Onreceive(uds_handle, uds_frame)

                        if uds_frame.id in self.condition_timestamps and self.condition_timestamps[uds_frame.id]['timestamp'] is None:
                            target_data = self.condition_timestamps[uds_frame.id]['data']
                            logging.debug(f"检查条件匹配: ID 0x{uds_frame.id:X} 目标数据: {target_data} 实际数据: {uds_frame.data[:len(target_data)] if target_data else 'None'}")
                            if target_data is None or uds_frame.data[:len(target_data)] == target_data:
                                self.condition_timestamps[uds_frame.id]['timestamp'] = rcv_canfd_msgs[i].timestamp / 1000000.0
                                logging.info(f"记录到ID 0x{uds_frame.id:X}条件匹配时间戳: {self.condition_timestamps[uds_frame.id]['timestamp']}")

                        # 新增间隔检测
                        interval = self.get_frame_interval(rcv_canfd_msgs[i].frame.can_id)
                        # if interval is not None:
                        #     logging.info(f"CANFD Frame ID 0x{rcv_canfd_msgs[i].frame.can_id:X} interval: {interval*1000:.2f}ms")

                        # 增加队列状态监控
                        # if self.log_queue.qsize() > 1000:
                        #     logging.warning(f"日志队列积压 {self.log_queue.qsize()} 条,可能影响实时性")
                        # 增加队列重试
                        for retry in range(3):
                            try:
                                log_entry = (
                                    rcv_canfd_msgs[i].timestamp/1000000,
                                    'CANFD', 
                                    self.chn_index+1,
                                    "TX" if (rcv_canfd_msgs[i].frame._pad & 0x8) else "RX",
                                    rcv_canfd_msgs[i].frame.can_id,
                                    rcv_canfd_msgs[i].frame.len,
                                    int(rcv_canfd_msgs[i].frame.brs),
                                    int(rcv_canfd_msgs[i].frame.esi),
                                    [rcv_canfd_msgs[i].frame.data[j] for j in range(rcv_canfd_msgs[i].frame.len)]
                                )
                                self.log_queue.put(log_entry, timeout=0.1)
                                break
                            except queue.Full:
                                if retry == 2:
                                    logging.error("日志队列已满,丢弃CANFD帧数据")
                                else:
                                    time.sleep(0.01)

                        frame_id = rcv_canfd_msgs[i].frame.can_id  
                        data = [rcv_canfd_msgs[i].frame.data[j] for j in range(rcv_canfd_msgs[i].frame.len)]
                        self._handle_received_signal(frame_id, data)
                time.sleep(0.01)
            # 发送终止信号前处理剩余数据
            while not self.log_queue.empty():
                time.sleep(0.1)
            self.log_queue.put(None)
            logging.info("exit receive")
        except Exception as e:
            logging.error(f"Error in Read_Thread_Func: {e}")

    def log_worker(self):
        """独立的日志处理线程"""
        batch_size = 50  # 批量处理条目数
        max_retry = 3    # 最大重试次数
        while True:
            batch = []
            try:
                # 批量获取提高效率
                while len(batch) < batch_size:
                    item = self.log_queue.get(block=True, timeout=0.1)
                    if item is None:
                        if batch:  # 处理剩余批次
                            self._process_batch(batch)
                        return
                    batch.append(item)
            except queue.Empty:
                if batch:
                    self._process_batch(batch)
                continue
            
            self._process_batch(batch)

    def _process_batch(self, batch):
        """批量处理日志条目"""
        try:
            with open(LOG_FILE_NAME, 'a') as f:
                for entry in batch:
                    # 解析日志条目并格式化
                    if entry[1] == 'CAN':
                        timestamp, proto, chn, direction, can_id, dlc, data = entry
                        data_str = ' '.join(f'{b:02X}' for b in data)
                        log_line = f"{timestamp:.6f} {proto} {chn} {direction} {can_id:X} {dlc} {data_str}"
                    elif entry[1] == 'CANFD':
                        timestamp, proto, chn, direction, can_id, len, brs, esi, data = entry
                        data_str = ' '.join(f'{b:02X}' for b in data)
                        log_line = f"{timestamp:.6f} {proto} {chn} {direction} {can_id:X} {len} {brs} {esi} {data_str}"
                    
                    # 调用原有日志保存方法
                    self.log_to_file(log_line)
        except Exception as e:
            logging.error(f"日志处理错误: {str(e)}")
        finally:
            self.log_queue.task_done()

    # 打开CAN设备并初始化通道的函数
    def Open_CAN(self):
        """
        打开CAN设备并初始化通道。
        :return: 设备句柄和通道句柄
        """
        try:
            # 打开设备
            self.device_handle = self.zcanlib.OpenDevice(self.device_type, self.device_index, 0)
            if self.device_handle == INVALID_DEVICE_HANDLE:
                logging.error("Open CANFD Device failed!")
                return None, None
            logging.info(f"Open CANFD Device success! device handle: 0x{self.device_handle:x}.")

            # 初始化并启动通道,同时开启队列发送模式
            self.chn_handle_0 = canfd_start(self.zcanlib, self.device_handle, self.chn_index, self.abit, self.bbit)
            logging.info(f"chn handle: 0x{self.chn_handle_0:x}.")
            return self.device_handle, self.chn_handle_0
        except Exception as e:
            logging.error(f"Error opening CAN device: {e}")
            return None, None

    def clear_buffer(self):
        """
        清空CAN缓冲区。
        """
        try:
            self.zcanlib.ClearBuffer(self.chn_handle_0)
        except Exception as e:
            logging.error(f"Error clearing buffer: {e}")
        
    def parse_dbc_to_list(self,dbcfile):
        """
        初始化DBC文件。
        :param dbcfile: DBC文件路径
        """
        try:
            self.zdbclib.load_dbc_file(dbcfile)
            logging.info(f"Load DBC file: {dbcfile} success!")
            signal_configs = self.zdbclib.parse_messages_to_list(1)
            return signal_configs
        except Exception as e:
            logging.error(f"Error loading DBC file: {e}")
            return []
        
    def handle_negative_response(self, response, recvData):
        """
        处理消极响应,记录日志并将相关数据添加到 recvData 列表中。
        :param response: UDS 响应结构体
        :param recvData: 用于存储接收数据的列表
        """
        # logging.info(f"消极响应：{hex(response.response.negative.neg_code)} 服务号： {hex(response.response.negative.sid)}  消极码： {hex(response.response.negative.error_code)}")
        recvData.append(response.response.negative.neg_code)
        # 这里原代码可能有误,消极响应没有 positive 相关属性,推测应该是添加消极响应的 sid 和 error_code
        recvData.append(response.response.negative.sid)
        recvData.append(response.response.negative.error_code)

        return recvData

    def handle_positive_response(self, response, recvData):
        """
        处理积极的响应,记录日志并将相关数据添加到 recvData 列表中。
        :param response: UDS 响应结构体
        :param recvData: 用于存储接收数据的列表
        """
        # logging.info(f"积极的响应,响应id:{hex(response.response.positive.sid)},参数长度:{response.response.positive.param_len},参数内容：{' '.join(hex(response.response.positive.param[i]) for i in range(response.response.positive.param_len))}")
        recvData.append(response.response.positive.sid)
        for i in range(response.response.positive.param_len):
             recvData.append(response.response.positive.param[i])

        return recvData
        

    # 发送UDS请求并处理响应的函数
    def req_and_res_can(self, data, len, udsFun = False, enblePrint = True):
        """
        发送UDS请求并处理响应。
        :param sid: 服务ID
        :param data_1: 请求参数
        """
        try:
            sid = data[0]
            data_1 = data[1:]
            request = ZUDS_REQUEST()
            memset(byref(request), 0, sizeof(request))
            if udsFun:
                request.src_addr = Set_up.AFctID
                request.dst_addr = Set_up.resID
            else:
                request.src_addr = Set_up.reqID
                request.dst_addr = Set_up.resID
            request.sid = sid
            request.suppress_response = 0
            request.param_len = len(data_1)
            param_data = PARAM_DATA()
            for i in range(request.param_len):
                param_data.data[i] = data_1[i]
            request.param = param_data.data
            response = ZUDS_RESPONSE()

            reqData = []
            reqData.append(sid)
            reqData.extend(data_1)


            self.zudslib.Uds_Request(self.uds_handle, request, response)
            memset(byref(param_data), 0, sizeof(param_data))

            recvData = []

            status_messages = {
                0: {
                    0: lambda recvData: self.handle_negative_response(response, recvData),
                    1: lambda recvData: self.handle_positive_response(response, recvData)
                },
                # 1: lambda: logging.info("响应超时"),
                # 2: lambda: logging.info("传输失败,请检查链路层,或请确认流控帧是否回复"),
                # 3: lambda: logging.info("取消请求"),
                # 4: lambda: logging.info("抑制响应"),
                # 5: lambda: logging.info("忙碌中"),
                # 6: lambda: logging.info("请求参数错误")
            }

            if response.status in status_messages:
                if response.status == 0:
                    if response.type in status_messages[0]:
                        # 传入 recvData 参数
                        recvData = status_messages[0][response.type](recvData)
                else:
                    # 这里原代码 lambda 没参数,保持调用方式
                    status_messages[response.status]()
            if enblePrint:
                sendstr = binascii.b2a_hex(bytearray(reqData),' ')
                logging.info('Send UDS ID : [0x{0:X}]'.format(request.src_addr))
                logging.info('Send UDS request size :{0} ---,the send data are <<<{1}>>>'.format(len(reqData),sendstr))

                readstr = binascii.b2a_hex(bytearray(recvData),' ')
                logging.info('Read UDS reponse size :{0} ---,the read data are <<<{1}>>>\n'.format(len(recvData),readstr))

            return recvData, len(recvData)
        except Exception as e:
            logging.error(f"Error in req_and_res_can: {e}")

    # 初始化UDS的函数
    def init_uds(self):
        """
        初始化UDS。
        :return: UDS句柄、通道参数和接收线程
        """
        try:
            self.uds_handle = self.zudslib.Uds_Init(0)
            if self.uds_handle is None:
                raise ValueError("UDS初始化失败")
            logging.info(f"uds_handle: 0x{self.uds_handle:x}.")

            self.chn_param = CHANNEL_PARAM()
            self.chn_param.channel_handle = self.chn_handle_0
            self.chn_param.Extend_Flag = 0
            self.chn_param.CANFD_type = 1
            self.chn_param.trans_version = 1

            self.Set_param(self.uds_handle, self.chn_param)

            ret = self.zudslib.Uds_SetTransmitHandler(self.uds_handle, byref(self.chn_param))
            if ret != 0:
                raise ValueError("Uds_SetTransmitHandler 调用失败")
            logging.info("Uds_SetTransmitHandler success")

            global START_RECEIVE_FLAG
            START_RECEIVE_FLAG = 1
            self.read_thread_ = threading.Thread(target=self.Read_Thread_Func, args=(self.chn_handle_0, self.uds_handle))
            self.read_thread_.start()

            return self.uds_handle, self.chn_param, self.read_thread_
        except Exception as e:
            logging.error(f"初始化UDS时发生错误: {e}")
            return None, None, None

    # 关闭CAN设备和UDS库的函数
    def close_can(self):
        """
        关闭CAN设备和UDS库。
        """
        try:
            time.sleep(1)
            global START_RECEIVE_FLAG
            START_RECEIVE_FLAG = 0
            if self.read_thread_.is_alive():
                self.read_thread_.join()

            if self.uds_handle is not None:
                self.zudslib.Uds_Release(self.uds_handle)

            if self.chn_handle_0 is not None:
                ret = self.zcanlib.ResetCAN(self.chn_handle_0)
                if ret == 1:
                    logging.info("ResetCAN success! ")

            if self.device_handle is not None:
                ret = self.zcanlib.CloseDevice(self.device_handle)
                if ret == 1:
                    logging.info("CloseDevice success! ")

            if self.log_thread.is_alive():
                self.log_thread.join() 

            self.zdbclib.__del__()
  
        except Exception as e:
            logging.error(f"关闭CAN设备时发生错误: {e}")

    def send_frame(self, ID, Data, type = "CANFD", print = False):
        transmit_num = 1
        try:
            if type == "CAN":
                # 数据长度校验（标准CAN最大8字节）
                if len(Data) > 8:
                    logging.warning(f"CAN数据长度超过8字节! 已截断前8字节 ID:0x{ID:X}")
                    Data = Data[:8]
                
                msgs = (ZCAN_Transmit_Data * transmit_num)()
                for i in range(transmit_num):
                    msgs[i].transmit_type = 0
                    msgs[i].frame.eff = 0
                    msgs[i].frame.rtr = 0
                    msgs[i].frame.can_id = ID
                    msgs[i].frame.can_dlc = len(Data)
                    for j in range(msgs[i].frame.can_dlc):
                        msgs[i].frame.data[j] = Data[j]
                ret = self.zcanlib.Transmit(self.chn_handle_0, msgs, transmit_num)
            else:
                # 发送 CANFD 报文
                canfd_msgs = (ZCAN_TransmitFD_Data * transmit_num)()
                for i in range(transmit_num):
                    canfd_msgs[i].transmit_type = 0
                    canfd_msgs[i].frame.eff = 0
                    canfd_msgs[i].frame.rtr = 0
                    canfd_msgs[i].frame.brs = 1  # BRS: 启用比特率切换
                    canfd_msgs[i].frame.esi = 0  # 明确设置ESI标志位
                    canfd_msgs[i].frame.can_id = ID
                    canfd_msgs[i].frame.len = len(Data)
                    for j in range(canfd_msgs[i].frame.len):
                        canfd_msgs[i].frame.data[j] = Data[j]
                ret = self.zcanlib.TransmitFD(self.chn_handle_0, canfd_msgs, transmit_num)
            if print:
                reqstr = binascii.b2a_hex(bytearray(Data), ' ')
                # 添加发送结果日志
                if ret == transmit_num:
                    logging.info(f"成功发送{transmit_num}帧 ID:0x{ID:X}, DATA:{reqstr}")
                else:
                    logging.error(f"发送失败 预期:{transmit_num} 实际:{ret}")
            return ret
        except Exception as e:
            logging.error(f"发送异常 ID:0x{ID:X} 错误:{str(e)}")
            return 0

    def _parse_frame_type(self, data):
        """智能帧类型解析器 (支持自动长度校验)"""
        if not data:
            return 'UNKNOWN', 0
            
        pci_map = {
            0x0: ('SF', 1),   # 单帧最小长度1字节
            0x1: ('FF', 2),   # 首帧最小长度2字节
            0x2: ('CF', 1),   # 连续帧最小长度1字节
            0x3: ('FC', 3)    # 新增流控帧,最小长度3字节
        }
        
        pci_type = (data[0] & 0xF0) >> 4
        frame_type, min_length = pci_map.get(pci_type, ('UNKNOWN', 0))
        
        # 自动长度校验
        if len(data) < min_length:
            return 'INVALID', 0
            
        if pci_type == 0x0:
            return frame_type, data[0] & 0x0F
        elif pci_type == 0x1:
            return frame_type, ((data[0] & 0x0F) << 8) + data[1]
        elif pci_type == 0x3:  # 流控帧处理
            return frame_type, (data[1], data[2])  # 返回(块大小, STmin)
        return frame_type, 0  # 连续帧无长度字段

    def recv_frame_by_id(self, target_id, can_type="CANFD", min_length=0, timeout=5):
        """统一帧接收器 (支持CAN/CANFD自动切换)"""
        frame_handlers = {
            "CAN": (ZCAN_TYPE_CAN, self.zcanlib.Receive),
            "CANFD": (ZCAN_TYPE_CANFD, self.zcanlib.ReceiveFD)
        }
        
        start_time = time.time()
        while time.time() - start_time < timeout:
            chn_type, receiver = frame_handlers.get(can_type, (None, None))
            # if not chn_type:
            #     logging.error(f"不支持的CAN类型: {can_type}")
            #     return None
                
            rcv_num = self.zcanlib.GetReceiveNum(self.chn_handle_0, chn_type)
            if not rcv_num:
                time.sleep(0.01)
                continue
                
            msgs, _ = receiver(self.chn_handle_0, rcv_num)
            for msg in msgs:
                if msg.frame.can_id == target_id:
                    # logging.info(f"收到帧 ID: {msg.frame.can_id:X}")
                    data_len = msg.frame.len if can_type == "CANFD" else msg.frame.can_dlc
                    data = [msg.frame.data[j] for j in range(data_len)]
                    if len(data) >= min_length:
                        return data
        return None

    def recv_iso_tp_data(self, target_id, can_Type = 'CANFD',timeout=5):
        """增强型ISO-TP接收器 (保留完整原始数据)"""
        session = {
            'start': time.time(),
            'expected_len': 0,
            'current_seq': 1,
            'raw_frames': [],  # 新增原始数据存储
            'max_dlc': 64 if can_Type == "CANFD" else 8
        }
        
        def remaining_time():
            return max(0, timeout - (time.time() - session['start']))
            
        while remaining_time() > 0:
            data = self.recv_frame_by_id(target_id, can_Type, timeout=min(0.5, remaining_time()))
            if not data:
                continue  
            frame_type, pdu_info = self._parse_frame_type(data)
            
            # 始终保存完整原始数据
            session['raw_frames'].append({
                'timestamp': time.time(),
                'frame_type': frame_type,
                'raw_data': data.copy()
            })
            if frame_type == 'FC':
                logging.info(f"收到流控帧,立即返回 原始数据:{self._hex_format(data)}")
                return session['raw_frames']

            if frame_type == 'SF':
                logging.info(f"收到单帧 原始数据:{self._hex_format(data)}")
                return session['raw_frames']  # 返回原始数据集合
                
            if frame_type == 'FF':
                session.update(expected_len=pdu_info)
                logging.info(f"收到首帧 总长度:{pdu_info} 原始数据:{self._hex_format(data)}")
                continue
                
            if frame_type == 'CF' and session['expected_len'] > 0:
                if (data[0] & 0x0F) == session['current_seq']:
                    # 保留连续帧全部数据
                    session['current_seq'] = (session['current_seq'] % 15) + 1
                    
                    if len(session['raw_frames']) * session['max_dlc'] >= session['expected_len'] + 2:
                        logging.info(f"收到完整数据,共 {len(session['raw_frames'])} 帧 原始数据:{self._hex_format(data)}")
                        return session['raw_frames']  # 返回所有原始帧

        logging.warning(f"超时未收到完整数据,已接收{len(session['raw_frames'])}帧原始数据")
        return session['raw_frames']
    
    def _hex_format(self, data):
        """辅助格式化十六进制数据"""
        return ' '.join(f"{b:02X}" for b in data)

    
    def monitor_signal_changes(self):
        """信号监控线程主函数"""
        previous_data = {}
        while self.signal_monitor_running.is_set():
            for signal_id in list(self.signal_data_dict.keys()):
                current_data = self.signal_data_dict.get(signal_id, [])
                # 首次记录或数据长度变化时触发更新
                if signal_id not in previous_data or len(current_data) != len(previous_data[signal_id]):
                    self._trigger_callback(signal_id, "INIT" if signal_id not in previous_data else "LENGTH_CHANGE")
                    previous_data[signal_id] = current_data.copy()
                    continue
                
                # 检查数据内容变化
                if current_data != previous_data[signal_id]:
                    changed_indices = [i for i, (curr, prev) in enumerate(zip(current_data, previous_data[signal_id])) if curr != prev]
                    self._trigger_callback(signal_id, "DATA_CHANGE", changed_indices)
                    previous_data[signal_id] = current_data.copy()
            
            time.sleep(self.signal_monitor_interval)

    def _trigger_callback(self, signal_id, change_type, changed_indices=None):
        """触发注册的回调函数"""
        if signal_id in self.signal_change_callbacks:
            try:
                self.signal_change_callbacks[signal_id](
                    signal_id,
                    self.signal_data_dict[signal_id],
                    change_type,
                    changed_indices
                )
            except Exception as e:
                logging.error(f"Signal callback error for ID {hex(signal_id)}: {str(e)}")

    def register_signal_monitor(self, signal_id, callback, interval=0.1):
        """
        注册信号监控
        :param signal_id: 要监控的信号ID
        :param callback: 回调函数格式: func(signal_id, current_data, change_type, changed_indices)
        :param interval: 监控间隔（秒）
        """
        self.signal_monitor_interval = interval
        self.signal_change_callbacks[signal_id] = callback
        
        # 首次启动监控线程
        if not self.signal_monitor_running.is_set():
            self.signal_monitor_running.set()
            self.signal_monitor_thread = threading.Thread(target=self.monitor_signal_changes)
            self.signal_monitor_thread.daemon = True
            self.signal_monitor_thread.start()

    def unregister_signal_monitor(self, signal_id):
        """注销信号监控"""
        if signal_id in self.signal_change_callbacks:
            del self.signal_change_callbacks[signal_id]


    def stop_all_monitoring(self):
        """停止所有监控"""
        self.signal_monitor_running.clear()
        self.signal_change_callbacks.clear()

    def send_signal_frame_loop(self, ID, signal_data, type="CANFD", interval=500):
        """
        循环发送指定信号CANFD帧的线程函数
        :param ID: 帧ID
        :param signal_data: 信号帧数据
        :param type: 帧类型,默认为CANFD
        :param interval: 发送间隔,默认为500ms
        """
        self.signal_data_dict[ID] = signal_data  # 初始化信号数据
        stop_event = self.signal_stop_event_dict[ID]
        pause_event = self.signal_pause_event_dict[ID]
        self.signal_cantype_dict[ID] = type

         # 新增时间补偿机制
        next_time = time.perf_counter()  # 使用高精度计时器
        # 新增：强制最小间隔
        interval = max(5, interval)  # 设置最小间隔为10ms
        interval_sec = interval / 1000    # 转换为秒

        while not stop_event.is_set():
            pause_event.wait()
            
            # 精确等待到下一个时间点
            while time.perf_counter() < next_time:
                if sys.platform == 'win32':
                    ctypes.windll.kernel32.SleepEx(1, True)  # 使用Windows API精确等待1ms
                else:
                    time.sleep(0.001)
            
            current_data = self.signal_data_dict.get(ID)
            if current_data:
                self.send_frame(ID, current_data, type)
            
            next_time += interval_sec  # 更新下次触发时间

    def start_multiple_signal_loops(self, signal_configs):
        """
        启动多个信号循环发送线程
        :param signal_configs: 从DBC解析的信号配置列表,每个元素为消息字典
        """
        # 新增信号处理逻辑
        for msg_config in signal_configs:
            msg_id = msg_config['id']
            
            # 检查信号是否已存在
            if msg_id in self.signal_thread_dict:
                logging.info(f"信号0x{msg_id:03X}已存在,跳过初始化")
                continue
                
            # 初始化信号数据
            cycle = msg_config.get('cycle_ms', 100)  # 默认100ms周期
            can_type = "CANFD" if msg_config.get('is_canfd', False) else "CAN"
            signal_data = msg_config.get('data', [0]*8)  # 默认8字节0数据
            
            # 创建线程控制事件
            stop_event = threading.Event()
            pause_event = threading.Event()
            pause_event.set()
            
            # 存储信号配置
            self.signal_stop_event_dict[msg_id] = stop_event
            self.signal_pause_event_dict[msg_id] = pause_event
            self.signal_data_dict[msg_id] = signal_data.copy()
            self.signal_cantype_dict[msg_id] = can_type
            
            # 启动信号发送线程
            signal_thread = threading.Thread(
                target=self.send_signal_frame_loop,
                args=(msg_id, signal_data, can_type, cycle),
                name=f"SignalThread_0x{msg_id:03X}"
            )
            signal_thread.daemon = True
            signal_thread.start()
            
            self.signal_thread_dict[msg_id] = signal_thread
            strData = binascii.b2a_hex(bytearray(signal_data),' ')
            logging.info(f"已启动信号0x{msg_id:03X}发送线程,周期{cycle}ms, data: {strData}, can_type: {can_type}")

    def _add_single_signal(self, signal_config):
        """
        新增单个信号发送线程
        :param signal_config: 信号配置字典
        """
        msg_id = signal_config['id']
        if msg_id in self.signal_thread_dict:
            logging.warning(f"信号0x{msg_id:03X}已存在")
            return False
            
        # 初始化信号数据
        cycle = signal_config.get('cycle_ms', 100)
        can_type = "CANFD" if signal_config.get('is_canfd', False) else "CAN"
        signal_data = signal_config.get('data', [0]*8)
        
        # 创建线程控制事件
        stop_event = threading.Event()
        pause_event = threading.Event()
        pause_event.set()
        
        # 存储信号配置
        self.signal_stop_event_dict[msg_id] = stop_event
        self.signal_pause_event_dict[msg_id] = pause_event
        self.signal_data_dict[msg_id] = signal_data.copy()
        self.signal_cantype_dict[msg_id] = can_type
        
        # 启动信号发送线程
        signal_thread = threading.Thread(
            target=self.send_signal_frame_loop,
            args=(msg_id, signal_data, can_type, cycle),
            name=f"SignalThread_0x{msg_id:03X}"
        )
        signal_thread.daemon = True
        signal_thread.start()
        
        self.signal_thread_dict[msg_id] = signal_thread
        strData = binascii.b2a_hex(bytearray(signal_data),' ')
        logging.info(f"已新增信号0x{msg_id:03X}发送线程,周期{cycle}ms, data: {strData}, can_type: {can_type}")
        return True

    def update_signal_data(self, ID, new_data=None, index=None, valueBytes=None, signal_name = '', value = None):
        """
        更新指定信号ID的数据（支持整体更新或按字节位置更新）
        :param ID: 信号ID
        :param new_data: 新的完整数据（可选）
        :param index: 要更新的字节位置（支持单个位置或位置列表）
        :param value: 要更新的字节值（支持单个值或值列表）
        """
        if ID not in self.signal_data_dict:
            logging.warning(f"No signal data found for ID {hex(ID)}")
            return

        # 按字节更新模式
        if index is not None and valueBytes is not None:
            current_data = self.signal_data_dict[ID].copy()
            
            # 统一处理为列表格式
            indices = [index] if isinstance(index, int) else index
            values = [valueBytes] if isinstance(valueBytes, int) else valueBytes
            
            if len(indices) != len(values):
                logging.error("索引列表和值列表长度不一致")
                return

            for i, v in zip(indices, values):
                if 0 <= i < len(current_data):
                    current_data[i] = v & 0xFF  # 确保值在0-255范围内
                else:
                    logging.error(f"无效索引 {i},数据长度为 {len(current_data)}")
            hex_data = ' '.join(f"0x{x:02X}" for x in current_data)
            logging.info(f"Updated signal data for ID {hex(ID)}: {hex_data}")
            
            self.signal_data_dict[ID] = current_data
        # 整体数据更新模式
        elif new_data is not None:
            self.signal_data_dict[ID] = new_data
            # hex_data = ' '.join(f"0x{x:02X}" for x in new_data)
            # logging.info(f"Updated signal data for ID {hex(ID)}: {hex_data}")
        else:
            # 修改为使用常量定义
            frame_type = FT_CANFD if self.signal_cantype_dict[ID] == "CANFD" else FT_CAN
            # 获取当前数据副本
            current_data = self.signal_data_dict.get(ID, []).copy()
            hex_data = ' '.join(f"0x{b:02X}" for b in current_data)
            # logging.info(f'获取信号{signal_name}现数据成功,数据内容: {hex_data}')

            tranData = self.zdbclib.update_signal_value(ID, signal_name, value, frame_type, current_data)

            # 增加数据有效性校验
            if tranData:
                # 转换c_ubyte数组为bytes类型
                if frame_type == FT_CANFD:
                    data_length = tranData.frame.len  # 获取实际数据长度
                else:
                    data_length = tranData.frame.can_dlc
                # 仅更新变化的字节
                updated_data = list(bytes(tranData.frame.data)[:data_length])
                # 保留未修改的字节
                merged_data = current_data[:]
                for i in range(min(len(updated_data), len(merged_data))):
                    if merged_data[i] != updated_data[i]:
                        merged_data[i] = updated_data[i]
                
                self.signal_data_dict[ID] = merged_data  # 存储合并后的数据
                
                hex_data = ' '.join(f"0x{b:02X}" for b in merged_data)
                logging.info(f"Updated signal data for ID {hex(ID)}: {hex_data}")
                # logging.info(f'更新信号{signal_name}值成功,数据内容: {hex_data}')
            else:
                logging.error(f"更新信号{signal_name}值失败,无效返回数据")

    def stop_signal_loop(self, ID):
        """
        停止指定信号的发送线程
        :param ID: 信号ID
        """
        if ID in self.signal_stop_event_dict:
            stop_event = self.signal_stop_event_dict[ID]
            stop_event.set()
            if ID in self.signal_thread_dict:
                thread = self.signal_thread_dict[ID]
                if thread.is_alive():
                    thread.join()
                del self.signal_thread_dict[ID]
                del self.signal_stop_event_dict[ID]
                del self.signal_data_dict[ID]
                del self.signal_pause_event_dict[ID]
            # logging.info(f"Stopped signal loop for ID {hex(ID)}")
        else:
            logging.warning(f"No signal loop found for ID {hex(ID)}")

    def pause_signal_loop(self, ID):
        """
        挂起指定信号的发送线程
        :param ID: 信号ID
        """
        # 添加ID类型验证
        if not isinstance(ID, (int, str)):
            raise TypeError(f"ID必须为可哈希类型(int/str),当前类型为{type(ID)}")
        if ID in self.signal_pause_event_dict:
            pause_event = self.signal_pause_event_dict[ID]
            pause_event.clear()  # 清除事件以挂起线程
            logging.info(f"Paused signal loop for ID {hex(ID)}")
        else:
            logging.warning(f"No signal loop found for ID {hex(ID)}")

    def resume_signal_loop(self, ID):
        """
        恢复指定信号的发送线程
        :param ID: 信号ID
        """
        # 添加ID类型验证
        if not isinstance(ID, (int, str)):
            raise TypeError(f"ID必须为可哈希类型(int/str),当前类型为{type(ID)}")
            
        if ID in self.signal_pause_event_dict:
            pause_event = self.signal_pause_event_dict[ID]
            pause_event.set()  # 设置事件以恢复线程
            logging.info(f"Resumed signal loop for ID {hex(ID)}")
        else:
            logging.warning(f"No signal loop found for ID {hex(ID)}")

    def get_signal_config_by_id(self, ID, signal_configs, signal_data, Cantype, cycle):
        """
        通过ID获取signal_configs里对应的值,如果没找到就新增信号
        :param ID: 要查找的ID
        :param signal_configs: 信号配置列表
        :return: 如果找到匹配的ID,返回对应的配置元组；否则新增信号并返回新增的配置元组
        """
        for config in signal_configs:
            if config[0] == ID:
                return config

        # 如果没找到,新增信号
        new_config = (ID, signal_data, Cantype, cycle)  # 这里假设新增的默认值为 (0, 0, 0),你可以根据实际情况修改
        return new_config
    
    def restart_signal_loop(self, ID, signal_data=[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], Cantype="CANFD", cycle=500):
        """
        重新启动指定信号的发送线程
        :param ID: 信号ID
        :param signal_data: 信号帧数据
        :param type: 帧类型,默认为CANFD
        :param interval: 发送间隔,默认为1秒
        """
        configs =  self.get_signal_config_by_id(ID, Set_up.signal_configs, signal_data, Cantype, cycle)

        if ID not in self.signal_thread_dict:
            stop_event = threading.Event()
            self.signal_stop_event_dict[ID] = stop_event
            signal_thread = threading.Thread(target=self.send_signal_frame_loop, args=(configs[0], configs[1], configs[2], configs[3]))
            signal_thread.daemon = True  # 设置为守护线程,主线程退出时自动退出
            signal_thread.start()
            self.signal_thread_dict[ID] = signal_thread
            self.signal_data_dict[ID] = signal_data
            # logging.info(f"Restarted signal loop for ID {hex(ID)}")
        else:
            logging.warning(f"Signal loop for ID {hex(ID)} is already running")
            

    def search_DTC(self, DTC_CMD,expect_DTC,timeout=5):
        start_time = time.time()
        Find_DTC = False
        rep_value = []
        while( (time.time()-start_time) < timeout):
            rep_value,rep_size = self.req_and_res_can(DTC_CMD, len(DTC_CMD), enblePrint=False)
            reponse_np = np.array(rep_value)[3:].reshape((-1,4))
            for data in reponse_np.tolist():
                # 根据expect_DTC长度进行切片匹配
                compare_length = min(len(expect_DTC), len(data))
                if list(expect_DTC[:compare_length]) == data[:compare_length]:
                    Find_DTC = True
                    break
                else:
                    Find_DTC = False
            if Find_DTC:
                break
        sendstr = binascii.b2a_hex(bytearray(DTC_CMD),' ')    
        totle_time = time.time()-start_time
        all_reponse = binascii.b2a_hex(bytearray(rep_value),' ')
        logging.info('Read DTC by CMD:{0}---,DTC [{4}] had found {1}---,Totle used time {2} ---, The All reponse are {3} '.format(
            sendstr,Find_DTC,totle_time,all_reponse, binascii.b2a_hex(bytearray(expect_DTC), ' ')))
        
        return Find_DTC,totle_time,rep_value
 
        
if __name__ == "__main__":
    uds_controller = UDSController()
    device_handle, chn_handle_0 = uds_controller.Open_CAN()
    uds_handle, chn_param, read_thread_ = uds_controller.init_uds()

    
    
    # # 定义更多信号的配置
    # signal_configs = Set_up.signal_configs
    
    # 修改调用方式（原代码中的函数定义需要删除）
    dbc_path = os.path.join(grand_parent_dir, "data/Kunlun_ETC_BodyCANFD_240501.dbc")
    db = DBCParser(dbc_path)
    signal_configs = db.parse_signals()

    logging.info(signal_configs)
    
    # 启动多个信号循环发送线程
    uds_controller.start_multiple_signal_loops(signal_configs)
    time.sleep(1)
    # 更改信号值
    for i in range(1):
            high_byte = (i >> 8) & 0xFF
            low_byte = i & 0xFF
            speed_data = [high_byte, low_byte]
            new_speed_data =speed_data +  [0x80, 0x00, 0x00, 0x00, 0x0, 0x00]
            uds_controller.update_signal_data(0x106, signal_name='VehicleSpeed', value=i)
            time.sleep(2)
            if i > 3:
                uds_controller.pause_signal_loop(0x90)
            if i > 5:
                uds_controller.resume_signal_loop(0x90)
    
    uds_controller.req_and_res_can([0x10,0x05], 2)
    uds_controller.close_can()